using System.Collections.Generic;
using System.Text;
using UnityEngine;

namespace Scanline.Core
{
    internal class ActiveEdgeContainer
    {
        private readonly LinkedList<OrderedEdge> edges;
        private readonly OrderedEdgeContainer orderedEdgeContainer;
        internal int currentY;

        internal bool End => currentY >= orderedEdgeContainer.yMax;  //下闭上开

        internal ActiveEdgeContainer(OrderedEdgeContainer orderedEdgeContainer)
        {
            edges = new();
            this.orderedEdgeContainer = orderedEdgeContainer;
            currentY = orderedEdgeContainer.yMin - 1;
        }

        internal void Add(OrderedEdge edge)
        {
            if (edges.Count == 0)
            {
                edges.AddFirst(edge);
            }
            else
            {
                LinkedListNode<OrderedEdge> current = edges.First;
                while (true)
                {
                    if(edge.sortingValue < current.Value.sortingValue)
                    {
                        edges.AddBefore(current, new LinkedListNode<OrderedEdge>(edge));
                        break;
                    }
                    if (current.Next == null)
                    {
                        edges.AddAfter(current, new LinkedListNode<OrderedEdge>(edge));
                        break;
                    }
                    current = current.Next;
                }
            }
        }

        /// <summary>
        /// 使扫描线上移，然后返回当前扫描线扫过的点
        /// </summary>
        /// <param name="ret">接收结果</param>
        internal void MoveUp(List<Vector2Int> ret)
        {
            int temp = 0;
            bool flag = false;  //控制两两配对
            currentY++;
            Debug.Log($"*{currentY}*");

            orderedEdgeContainer.SendCurrentEdges(this);
            if (edges.Count > 0)
            {
                for (LinkedListNode<OrderedEdge> current = edges.First; current != null;)
                {
                    OrderedEdge currentEdge = current.Value;
                    if (currentY >= currentEdge.yMax)  //下闭上开
                    {
                        LinkedListNode<OrderedEdge> next = current.Next;
                        edges.Remove(current);
                        current = next;
                    }
                    else
                    {
                        int intersection = currentEdge.MoveUp();
                        if (flag)
                        {
                            GetRange(temp, intersection, ret);
                            flag = false;
                        }
                        else
                        {
                            temp = intersection;
                            flag = true;
                        }
                        current = current.Next;
                    }
                }
            }
        }

        private void GetRange(int x1, int x2, List<Vector2Int> ret)
        {
            if (x1 > x2)
            {
                GetRange(x2, x1, ret);
                return;
            }
            for (int i = x1; i < x2; i++)
            {
                ret.Add(new Vector2Int(i, currentY));   //左闭右开
            }
        }

        public override string ToString()
        {
            StringBuilder sb = new();
            sb.AppendLine($"currentY:{currentY}");
            foreach (OrderedEdge edge in edges)
            {
                sb.AppendLine(edge.ToString());
            }
            return sb.ToString();
        }
    }
}